package com.canaan.business.service.storehouse.impl;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.alibaba.druid.sql.visitor.functions.If;
import com.canaan.business.common.enums.basic.YNEnum;
import com.canaan.business.common.enums.productBom.ProductTypeEnum;
import com.canaan.business.domain.basic.WmsProduct;
import com.canaan.business.mapper.storehouse.WmsStorehouseStockMapper;
import com.canaan.business.service.basic.IWmsProductService;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.TableNoUtil;
import com.canaan.common.utils.StringUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import com.canaan.business.mapper.storehouse.StockStageMapper;
import com.canaan.business.domain.storehouse.StockStage;
import com.canaan.business.service.storehouse.IStockStageService;
import org.springframework.util.CollectionUtils;

/**
 * 库存水位管理Service业务层处理
 *
 * @author ruoyi
 * @date 2023-02-13
 */
@Service
public class StockStageServiceImpl implements IStockStageService {
    @Resource
    private StockStageMapper stockStageMapper;

    @Resource
    private WmsStorehouseStockMapper storehouseStockMapper;

    @Resource
    private IWmsProductService wmsProductService;

    /**
     * 查询库存水位管理
     *
     * @param id 库存水位管理主键
     * @return 库存水位管理
     */
    @Override
    public StockStage selectStockStageById(Long id) {
        return stockStageMapper.selectStockStageById(id);
    }

    /**
     * 查询库存水位管理列表
     *
     * @param stockStage 库存水位管理
     * @return 库存水位管理
     */
    @Override
    public List<StockStage> selectStockStageList(StockStage stockStage) {
        return stockStageMapper.selectStockStageList(stockStage);
    }

    /**
     * 新增库存水位管理
     *
     * @param stockStage 库存水位管理
     * @return 结果
     */
    @Override
    public int insertStockStage(StockStage stockStage) {
        if (StringUtils.isEmpty(stockStage.getProductNo()) && StringUtils.isEmpty(stockStage.getProductType())){
            throw new ServiceException("请选择物料或物料类型");
        }
        if (stockStage.getSafetyStock() == null){
            throw new ServiceException("安全库存不能为空!");
        }
        if (stockStage.getMaximumStock() == null){
            throw new ServiceException("最高库存不能为空!");
        }
        if (stockStage.getMinimumStock() == null){
            throw new ServiceException("最低库存不能为空!");
        }

        // 需要判重,如果选择了物料，需要与原先数据做判断
        if (StringUtils.isNotEmpty(stockStage.getProductNo())){
            StockStage oldStage = this.selectByProductNoOrType(null,stockStage.getProductNo(),null);
            if (oldStage != null){
                throw new ServiceException("物料[" + stockStage.getProductNo() + "已存在水位管理");
            }
            WmsProduct product = this.wmsProductService.selectWmsProductByProductNo(stockStage.getProductNo());
            if(product == null){
                throw new ServiceException("所选物料数据不匹配!");
            }
        }else {
            StockStage oldStage = this.selectByProductNoOrType(null,null,stockStage.getProductType());
            if (oldStage != null){
                throw new ServiceException("物料类型[" + stockStage.getProductType() + "已存在水位管理");
            }
        }


        if((stockStage.getMinimumStock() != null && stockStage.getMaximumStock() != null) && (stockStage.getMaximumStock() < stockStage.getMinimumStock())){
            throw new ServiceException("最低库存不能高于最高库存!");
        }
        if(stockStage.getMinimumStock() > stockStage.getSafetyStock() || stockStage.getSafetyStock() > stockStage.getMaximumStock()){
            throw new ServiceException("安全库存需要在最高库存和最低库存之间!");
        }

        if(StringUtils.isBlank(stockStage.getNo())){
            stockStage.setNo(TableNoUtil.getNo(StockStage.class));
        }
        stockStage.setCreateBy(SecurityUtils.getUsername());
        stockStage.setCreateTime(DateUtils.getNowDate());
        return stockStageMapper.insertStockStage(stockStage);
    }

    /**
     * 批量新增库存水位管理
     *
     * @param stockStageList 库存水位管理列表
     * @return 结果
     */
    @Override
    public int batchInsertStockStage(List<StockStage> stockStageList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (StockStage stockStage : stockStageList){
            if(StringUtils.isBlank(stockStage.getNo())){
                stockStage.setNo(TableNoUtil.getNo(StockStage.class));
            }
            stockStage.setCreateBy(username);
            stockStage.setCreateTime(currerTime);
        }
        int insertNum = 0;
        for (int i=0; i<stockStageList.size();) {
            int endIndex = i+500;
            if (endIndex > stockStageList.size()) {
                endIndex = stockStageList.size();
            }
            insertNum = insertNum + stockStageMapper.batchInsertStockStage(stockStageList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }

    /**
     * 修改库存水位管理
     *
     * @param stockStage 库存水位管理
     * @return 结果
     */
    @Override
    public int updateStockStage(StockStage stockStage) {
        if (StringUtils.isEmpty(stockStage.getProductNo()) && StringUtils.isEmpty(stockStage.getProductType())){
            throw new ServiceException("请选择物料或物料类型");
        }
        if (stockStage.getSafetyStock() == null){
            throw new ServiceException("安全库存不能为空!");
        }
        if (stockStage.getMaximumStock() == null){
            throw new ServiceException("最高库存不能为空!");
        }
        if (stockStage.getMinimumStock() == null){
            throw new ServiceException("最低库存不能为空!");
        }

        // 需要判重,如果选择了物料，需要与原先数据做判断
        if (StringUtils.isNotEmpty(stockStage.getProductNo())){
            StockStage oldStage = this.selectByProductNoOrType(stockStage.getId(),stockStage.getProductNo(),null);
            if (oldStage != null){
                throw new ServiceException("物料[" + stockStage.getProductName() + "已存在水位管理");
            }
            WmsProduct product = this.wmsProductService.selectWmsProductByProductNo(stockStage.getProductNo());
            if(product == null){
                throw new ServiceException("所选物料数据不匹配!");
            }
        }else {
            StockStage oldStage = this.selectByProductNoOrType(stockStage.getId(),null,stockStage.getProductType());
            if (oldStage != null){
                throw new ServiceException("该物料类型已存在水位管理");
            }
        }
        stockStage.setUpdateBy(SecurityUtils.getUsername());
        stockStage.setUpdateTime(DateUtils.getNowDate());

        if((stockStage.getMinimumStock() != null && stockStage.getMaximumStock() != null) && (stockStage.getMaximumStock() < stockStage.getMinimumStock())){
            throw new ServiceException("最低库存不能高于最高库存!");
        }
        if(stockStage.getMinimumStock() > stockStage.getSafetyStock() || stockStage.getSafetyStock() > stockStage.getMaximumStock()){
            throw new ServiceException("安全库存需要在最高库存和最低库存之间!");
        }

        return stockStageMapper.updateStockStage(stockStage);
    }

    /**
     * 批量修改库存水位管理
     *
     * @param stockStageList 库存水位管理列表
     * @return 结果
     */
    @Override
    public int batchUpdateStockStage(List<StockStage> stockStageList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (StockStage stockStage : stockStageList){
            stockStage.setUpdateBy(username);
            stockStage.setUpdateTime(currerTime);
        }
        int updateNum = 0;
        for (int i=0; i<stockStageList.size();) {
            int endIndex = i+500;
            if (endIndex > stockStageList.size()) {
                endIndex = stockStageList.size();
            }
            updateNum = updateNum + stockStageMapper.batchUpdateStockStage(stockStageList.subList(i, endIndex));
            i = endIndex;
        }
        return updateNum;
    }

    /**
     * 批量删除库存水位管理
     *
     * @param ids 需要删除的库存水位管理主键集合
     * @return 结果
     */
    @Override
    public int deleteStockStageByIds(Long[] ids) {
        return stockStageMapper.deleteStockStageByIds(ids);
    }

    /**
     * 删除库存水位管理信息
     *
     * @param id 库存水位管理主键
     * @return 结果
     */
    @Override
    public int deleteStockStageById(Long id) {
        return stockStageMapper.deleteStockStageById(id);
    }

    /**
     * 查询库存水位管理
     *
     * @param no 编号
     * @return 库存水位管理
     */
    @Override
    public StockStage selectStockStageByNo(String no) {
        return stockStageMapper.selectStockStageByNo(no);
    }

    /**
     * 批量删除库存水位管理
     *
     * @param nos 需要删除的编号集合
     * @return 结果
     */
    @Override
    public int deleteStockStageByNos(String[] nos) {
        return stockStageMapper.deleteStockStageByNos(nos);
    }

    /**
     * 删除库存水位管理信息
     *
     * @param no 编号
     * @return 结果
     */
    @Override
    public int deleteStockStageByNo(String no) {
        return stockStageMapper.deleteStockStageByNo(no);
    }

    @Override
    public List<String> importExcel(List<StockStage> list) {
        List<String> errorList = Lists.newArrayList();

        // 校验是否存在重复数据
        List<String> productNos = list.stream().map(StockStage::getProductNo).collect(Collectors.toList());
        StockStage searchStockStage = new StockStage();
        searchStockStage.setProductNos(productNos);
        List<StockStage> productStageList = this.selectStockStageList(searchStockStage);
        Map<String,StockStage> productStogeMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(productStageList)){
            productStogeMap = productStageList.stream().collect(Collectors.toMap(StockStage::getProductNo, Function.identity(), (key1, key2) -> key2));
        }
        StockStage searchTypeStockStage = new StockStage();
        searchTypeStockStage.setProductIsNull(YNEnum.Y.getCode());
        List<StockStage> typeStageList = this.selectStockStageList(searchTypeStockStage);
        Map<String,StockStage> productTypeStogeMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(typeStageList)){
            productTypeStogeMap = typeStageList.stream().collect(Collectors.toMap(StockStage::getProductType, Function.identity(), (key1, key2) -> key2));
        }
        List<String> fileProductNos = new ArrayList<>();
        List<String> fileTypes = new ArrayList<>();
        // 循环校验数据是否重复
        for (int i = 0; i < list.size(); i++) {
            StockStage fileStockStage = list.get(i);
            if (fileStockStage.getSafetyStock() == null){
                errorList.add("第" + ( i + 1 ) + "行安全库存不能为空!");
            }
            if (fileStockStage.getMaximumStock() == null){
                errorList.add("第" + ( i + 1 ) + "行最高库存不能为空!");
            }
            if (fileStockStage.getMinimumStock() == null){
                errorList.add("第" + ( i + 1 ) + "行最低库存不能为空!");
            }
            if (StringUtils.isEmpty(fileStockStage.getProductNo()) && StringUtils.isEmpty(fileStockStage.getProductType())){
                errorList.add("第" + ( i + 1 ) + "行物料编码和物料类型不能同时为空!");
            }
            if (StringUtils.isNotEmpty(fileStockStage.getProductNo())){
                if (productStogeMap.get(fileStockStage.getProductNo()) != null){
                    errorList.add("第" + ( i + 1 ) + "行物料已维护水位管理数据!");
                }
                if (fileProductNos.contains(fileStockStage.getProductNo())){
                    errorList.add("第" + ( i + 1 ) + "行物料在文档中存在重复数据!");
                }
                WmsProduct product = this.wmsProductService.selectWmsProductByProductNo(fileStockStage.getProductNo());
                if(product == null){
                    errorList.add("第" + ( i + 1 ) + "行所选物料数据不匹配!");
                }else {
                    fileStockStage.setProductName(product.getProductName());
                }
                fileProductNos.add(fileStockStage.getProductNo());
            }else {
                fileStockStage.setProductType(ProductTypeEnum.getCodeByMessage(fileStockStage.getProductType()));
                if (productTypeStogeMap.get(fileStockStage.getProductType()) != null){
                    errorList.add("第" + ( i + 1 ) + "行所选物料类型已维护水位管理数据!");
                }
                if (fileTypes.contains(fileStockStage.getProductType())){
                    errorList.add("第" + ( i + 1 ) + "行所选物料类型在文档中存在重复数据!");
                }
                fileTypes.add(fileStockStage.getProductType());
            }


            if(list.get(i).getMinimumStock() < list.get(i).getMinimumStock()){
                throw new ServiceException("第" + ( i + 1 ) + "行最低库存不能高于最高库存!");
            }

            if(list.get(i).getMinimumStock() > list.get(i).getSafetyStock() || list.get(i).getSafetyStock() > list.get(i).getMaximumStock()){
                throw new ServiceException("第" + ( i + 1 ) + "行安全库存需要在最高库存和最低库存之间!");
            }
        }

        if(errorList.size() > 0){
            return errorList;
        }

        this.batchInsertStockStage(list);

        return errorList;
    }


    /**
     * 根据物料编号或物料类型，查询库存水位管理（用于判重）
     *
     * @param id 库存水位管理主键
     * @param productNo 物料编号
     * @param productType 物料类型
     * @return 库存水位管理
     */
    private StockStage selectByProductNoOrType(Long id,String productNo,String productType) {
        return stockStageMapper.selectByProductNoOrType(id,productNo,productType);
    }
}
